/*
 * @Author: chendeji
 * @Date: 2021-11-16 11:12:58
 * @LastEditTime: 2021-11-16 12:21:14
 * @Description: 
 * @FilePath: \copy_gsy_github_app_flutter\lib\repository\user_repository.dart
 * 联系方式：
 * wx: melody_2009
 * qq: 7815171323 
 */

import 'dart:convert';

import 'package:copy_gsy_github_app_flutter/common/config/config.dart';
import 'package:copy_gsy_github_app_flutter/common/config/ignoreConfig.dart';
import 'package:copy_gsy_github_app_flutter/common/model/User.dart';
import 'package:copy_gsy_github_app_flutter/common/net/address.dart';
import 'package:copy_gsy_github_app_flutter/common/net/api.dart';
import 'package:copy_gsy_github_app_flutter/common/sp/local_storage.dart';
import 'package:copy_gsy_github_app_flutter/db/provider/user/userinfo_db_provider.dart';
import 'package:dio/dio.dart';

import 'dao_result.dart';

class UserRepository {
  static oauth(String code) async {
    httpManager.clearAuthorization();
    var res = await httpManager.netFetch(
      "https://github.com/login/oauth/access_token?"
      "client_id=${NetConfig.CLIENT_ID}"
      "&client_secret=${NetConfig.CLIENT_SECRET}"
      "&code=${code}",
      null,
      null,
      new Options(method: "POST"),
    );
    dynamic resultData = null;
    if (res != null && res.result) {
      print("#### ${res.data}");
      var result = Uri.parse("gsy://oauth?" + res.data);
      var token = result.queryParameters["access_token"]!;
      var _token = 'token ' + token;
      await LocalStorage.save(Config.TOKEN_KEY, _token);

      resultData = await getUserInfo(null);
      if (Config.DEBUG!) {
        print("user result " + resultData.result.toString());
        print(resultData.data);
        print(res.data.toString());
      }
    }

    return DataResult(resultData, res!.result);
  }

  ///获取本地登录用户信息
  static getUserInfoLocal() async {
    var userText = await LocalStorage.get(Config.USER_INFO);
    if (userText != null) {
      var userMap = json.decode(userText);
      User user = User.fromJson(userMap);
      return new DataResult(user, true);
    } else {
      return new DataResult(null, false);
    }
  }

  static getUserInfo(userName, {needDb = false}) async {
    UserInfoDBProvider provider = UserInfoDBProvider();

    /// 内嵌的函数，用完就释放，可当做参数传递
    request() async {
      var res;
      if (userName == null) {
        res = await httpManager.netFetch(
            Address.getMyUserInfo(), null, null, null);
      } else {
        res = await httpManager.netFetch(
            Address.getUserInfo(userName), null, null, null);
      }
      if (res != null && res.result) {
        String? starred = "---";
        if (res.data["type"] != "Organization") {
          var countRes = await getUserStaredCountNet(res.data["login"]);
          if (countRes.result) {
            starred = countRes.data;
          }
        }
        User user = User.fromJson(res.data);
        user.starred = starred;
        if (userName == null) {
          LocalStorage.save(Config.USER_INFO, json.encode(user.toJson()));
        } else {
          if (needDb) {
            provider.insert(userName, json.encode(user.toJson()));
          }
        }
        return new DataResult(user, true);
      } else {
        return new DataResult(res.data, false);
      }
    }

    if (needDb) {
      User? user = await provider.getUserInfo(userName);
      if (user == null) {
        return await request();
      }
      DataResult dataResult = new DataResult(user, true, next: request);
      return dataResult;
    }
    return await request();
  }

  static getUserStaredCountNet(userName) async {
    String url = Address.userStar(userName, null) + "&per_page=1";
    var res = await httpManager.netFetch(url, null, null, null);
    if (res != null && res.result && res.headers != null) {
      try {
        List<String>? link = res.headers['link'];
        if (link != null) {
          int indexStart = link[0].lastIndexOf("page=") + 5;
          int indexEnd = link[0].lastIndexOf(">");
          if (indexStart >= 0 && indexEnd >= 0) {
            String count = link[0].substring(indexStart, indexEnd);
            return new DataResult(count, true);
          }
        }
      } catch (e) {
        print(e);
      }
    }
    return new DataResult(null, false);
  }
}
